﻿/****************************************************************************
** Copyright (C) 2017 ZhouLiQiu(zhouliqiu@126.com).
**
** This file is part of the qtc_astyle, It is a plugin for Qt Creator.
**
** Permission is hereby granted, free of charge, to any person obtaining a copy
** of this software and associated documentation files (the "Software"), to deal
** in the Software without restriction, including without limitation the rights
** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
** copies of the Software, and to permit persons to whom the Software is
** furnished to do so, subject to the following conditions:
**
** The above copyright notice and this permission notice shall be included in
** all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
** THE SOFTWARE.
**
****************************************************************************/
#include "astyleplugin.h"
#include "astyleplugin_p.h"
#include "astyleconstants.h"

#include <coreplugin/icore.h>
#include <coreplugin/icontext.h>
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/command.h>
#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/coreconstants.h>

#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/editormanager/ieditor.h>
#include <projectexplorer/projectexplorer.h>

#include <QAction>
#include <QMessageBox>
#include <QMainWindow>
#include <QMenu>
#include <QTranslator>

#include <QPlainTextEdit>

#include <QtPlugin>

#include "formstyleoption.h"
#include "formtaboption.h"
#include "formpadoption.h"
#include "formindentoption.h"
#include "formformatoption.h"

#include "astyleactions.h"

#include "cartisticstyle.h"
#include "cdlgformatproject.h"

namespace AStyle {
namespace Internal {
///////////////////////////////////////////////////////////////////////
//
// AStylePluginPrivate
//
///////////////////////////////////////////////////////////////////////

AStylePluginPrivate::AStylePluginPrivate(AStylePlugin *plugin)
{
    q = plugin;
    m_stylePage = new FormStyleOption(q);
    m_indentPage = new FormIndentOption(q);
    m_tabPage = new FormTabOptioin(q);
    m_padPage = new FormPadOption(q);
    m_formatPage = new FormFormatOption(q);
}

AStylePluginPrivate::~AStylePluginPrivate()
{
}

bool AStylePluginPrivate::initialize()
{
    QAction *actionFile = new QAction(QString::fromLocal8Bit("格式化当前文件"), q);
    Core::Command *cmdFile = Core::ActionManager::registerAction(actionFile, Constants::ACTION_FILE_ID,
                             Core::Context(Core::Constants::C_GLOBAL));
    cmdFile->setDefaultKeySequence(QKeySequence(("Alt+F8")));
    connect(actionFile, &QAction::triggered, this, &AStylePluginPrivate::triggerActionFile);

    QAction *actionProject = new QAction(QString::fromLocal8Bit("格式化当前项目"), q);
    Core::Command *cmdProject = Core::ActionManager::registerAction(actionProject, Constants::ACTION_PROJECT_ID,
                                Core::Context(Core::Constants::C_GLOBAL));
    connect(actionProject, &QAction::triggered, this, &AStylePluginPrivate::triggerActionProject);

    Core::ActionContainer *menu = Core::ActionManager::createMenu(Constants::MENU_ID);
    menu->menu()->setTitle(QString::fromLocal8Bit("代码格式化"));
    menu->addAction(cmdFile);
    menu->addAction(cmdProject);
    Core::ActionManager::actionContainer(Core::Constants::M_TOOLS)->addMenu(menu);

    readSettings();

    return true;
}

void AStylePluginPrivate::aboutToShutdown()
{
}

void AStylePluginPrivate::writeSettings()
{
    QSettings *settings = Core::ICore::settings();
    theAStyleSettings()->writeSettings(settings);
}

void AStylePluginPrivate::readSettings()
{
    QSettings *settings = Core::ICore::settings();
    theAStyleSettings()->readSettings(settings);
}

void AStylePluginPrivate::triggerActionFile()
{
    const Core::EditorManager *editorManager = Core::EditorManager::instance();
    if (!editorManager)
    {
        return;
    }
    Core::IEditor *editor = editorManager->currentEditor();
    if (!editor)
    {
        return;
    }
    Core::IDocument *idoc = editor->document();
    if (!idoc)
    {
        return;
    }
    QPlainTextEdit *textEditor = qobject_cast<QPlainTextEdit *>(editor->widget());
    if (!textEditor)
    {
        return;
    }

    QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
    CArtisticStyle art;
    art.formatEditor(textEditor);
    QApplication::restoreOverrideCursor();
}

void AStylePluginPrivate::triggerActionProject()
{
    CDlgFormatProject dlg;
    dlg.exec();
}

///////////////////////////////////////////////////////////////////////
//
// AStylePlugin
//
///////////////////////////////////////////////////////////////////////

AStylePlugin::AStylePlugin()
    : d(new AStylePluginPrivate(this))
{
    // Create your members
}

AStylePlugin::~AStylePlugin()
{
    // Unregister objects from the plugin manager's object pool
    // Delete members
    delete d;
}

bool AStylePlugin::initialize(const QStringList &arguments, QString *errorString)
{
    Q_UNUSED(arguments)
    Q_UNUSED(errorString)

    return d->initialize();
}

void AStylePlugin::extensionsInitialized()
{
    // Retrieve objects from the plugin manager's object pool
    // In the extensionsInitialized function, a plugin can be sure that all
    // plugins that depend on it are completely initialized.
}

ExtensionSystem::IPlugin::ShutdownFlag AStylePlugin::aboutToShutdown()
{
    // Save settings
    // Disconnect from signals that are not needed during shutdown
    // Hide UI (if you add UI that is not in the main window directly)
    d->aboutToShutdown();
    return SynchronousShutdown;
}

} // namespace Internal
} // namespace AStyle
